package cn.com.cifi.mars.web.action.fileUpload;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import cn.com.cifi.mars.bean.vo.price.FileDeleteVO;
import cn.com.cifi.mars.bean.vo.price.FilePreviewVO;
import cn.com.cifi.mars.bean.vo.price.FileUploadVO;
import cn.com.cifi.mars.common.base.BaseAction;
import cn.com.cifi.mars.common.bean.R;
import cn.com.cifi.mars.common.exception.MsgException;
import cn.com.cifi.mars.constant.CodeEnum;
import cn.com.cifi.mars.constant.IsDeleteEnum;
import cn.com.cifi.mars.entity.UploadFile;
import cn.com.cifi.mars.entity.common.IdmUser;
import cn.com.cifi.mars.service.FileUploadService;
import cn.com.cifi.mars.util.FileUtils;
import lombok.extern.slf4j.Slf4j;

/**
 * 
 * @author Administrator
 *
 */
@Slf4j
@RestController
public class FileUpload extends BaseAction implements IFileUpload{
    
	private static final Logger logger = LoggerFactory.getLogger(FileUpload.class);
    
    @Autowired
    FileUploadService fileUploadService;
    
    @Value("${file_directory}")
    private String fileDirectory;
    
    @Value("${approval_file_directory}")
    private String approvalFileDirectory;
    
    @Value("${pre_view_url}")
    private String preViewUrl;
    
    @Value("${download_url}")
    private String downloadUrlStr;
    
    @Override
    public R<FileUploadVO> fileUpload(String apiVersion, String projectId, MultipartFile file) {

    	if(file == null || file.isEmpty()) {
    		throw new MsgException(CodeEnum.FILE_IS_NULL);
    	}

        FileUploadVO uplpoadVO = new FileUploadVO();
        IdmUser user = getOperator();
        String account = user.getAlias();
//        String downloadUrl = downloadUrlStr;

        String fileName = file.getOriginalFilename();

        //获取后缀名
        String sname = fileName.substring(fileName.lastIndexOf("."));
        //文件扩展名
        String extName = sname.substring(1).toLowerCase();
        //设置转换类型
//        String convertType = "3";
//        //根据扩展名选择转换类型convertType
//        if (extName.equals("jpg") || extName.equals("png") || extName.equals("gif")){
//            convertType = "32";
//        }else if (extName.equals("zip") || extName.equals("rar")){
//            convertType = "19";
//        }else if (extName.equals("pdf")){
//            convertType = "34";
//        }else if (extName.equals("tif")){
//            convertType = "17";
//        }
        //截取文件名字(不带后缀)
        int i = fileName.lastIndexOf(".");
        String nameStr = fileName.substring(0, i);
        //时间格式化格式
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        //获取当前时间并作为时间戳
        String timeStamp = simpleDateFormat.format(new Date());
        //拼接新的文件名
        String newFileName = nameStr+"_"+timeStamp+sname;

        List<UploadFile> uploadFile = fileUploadService.selectSameFileName(newFileName);
        if (uploadFile.size() > 0){
            throw new MsgException(CodeEnum.FILE_NAME_EXISTENT);
        }

        String newFilePath = null;
        String id = null;
        //上传文件
        try {
            newFilePath = fileDirectory + approvalFileDirectory + newFileName;
            InputStream ins = file.getInputStream();
            File toFile  = new File(newFilePath);
            FileUtils.inputStreamToFile(ins, toFile);
            ins.close();
            id = fileUploadService.saveFileUploadRecord(newFileName,sname,newFilePath,fileName,account);
        } catch (Exception e) {
            throw new MsgException(CodeEnum.FILE_UPLOAD_ERROR);
        }
        
//        CloseableHttpClient client = HttpClients.createDefault();
//        //在线预览转换
//        try {
//            HttpPost httpPost = new HttpPost(preViewUrl);
//            List<NameValuePair> param = new ArrayList<>();
//            param.add(new BasicNameValuePair("convertType",convertType));
//            param.add(new BasicNameValuePair("downloadUrl",downloadUrl+id));
//            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(param, "utf-8");
//            httpPost.setEntity(formEntity);
//            CloseableHttpResponse response = client.execute(httpPost);
//            try {
//                // 获取响应实体
//                HttpEntity entity = response.getEntity();
//                if (response.getStatusLine().getStatusCode() == 200){
//                    if (entity != null) {
//                        // 打印响应内容
//                        String content = EntityUtils.toString(entity);
//                        JSONObject jsonObject = JSONObject.parseObject(content);
//                        JSONArray JsonData = jsonObject.getJSONArray("data");
//                        Integer result = jsonObject.getInteger("result");
//                        String message = jsonObject.getString("message");
//                        if (result == 0){
//                            if (null != JsonData && JsonData.size()>0){
//                                for (Object data : JsonData) {
//                                    String urlStr = data.toString();
//                                    //将预览地址更新到上传表
//                                    fileUploadService.updatePreViewUrl(id,urlStr);
//                                }
//                            }
//                        }else {
//                            uplpoadVO.setMessage(message);
//                        }
//                    }
//                }
//            } finally {
//                response.close();
//            }
//        } catch (IOException e) {
//            log.error("###### errorMsg: ", e);
//        }finally {
//            try {
//                // 关闭连接,释放资源
//                client.close();
//            } catch (IOException e) {
//                log.error("###### errorMsg: ", e);
//            }
//        }
        UploadFile fileById = fileUploadService.selectFileById(id);

        uplpoadVO.setFilePath(newFilePath);
        uplpoadVO.setFileId(id);
        uplpoadVO.setFileName(fileName);
        uplpoadVO.setFileType(sname.substring(1));
        uplpoadVO.setPreviewUrl(fileById.getPreViewUrl());
        return ok(uplpoadVO);
    }

    @Override
    public void download(String apiVersion, String fileId, HttpServletRequest request,
                                        HttpServletResponse response) {
    	// path是指欲下载的文件的路径。
        String address = null;
        UploadFile uploadFile = fileUploadService.selectFileById(fileId);
        if (null != uploadFile){
            address = uploadFile.getFileStoreAddress();
        }
        File file = null;
        if (StringUtils.isNotBlank(address)){
            file = new File(address);
        }
        // 如果文件不存在
        if(file!=null) {
        	if (!file.exists()) {
                throw new MsgException(CodeEnum.FILE_IS_NOT_EXISTENT);
            }
        	// 文件名
            String filename = file.getName();
            String userAgent = request.getHeader("USER-AGENT");
            if (userAgent.contains("Firefox")){
                try {
    				filename = "=?utf-8?b?"+ Base64.getEncoder().encode(filename.getBytes("utf-8"))+"?=";
    			} catch (UnsupportedEncodingException e) {
    				log.error(e.getMessage());
    			}
            }else {
                try {
    				filename = URLEncoder.encode(filename,"utf-8");
    			} catch (UnsupportedEncodingException e) {
    				log.error(e.getMessage());
    			}
            }
            byte[] buffer =null;
        	try(InputStream fis = new BufferedInputStream(new FileInputStream(address));
        		 ) {
                // 以流的形式下载文件。
                buffer = new byte[fis.available()];
                int count=fis.read(buffer);
                log.info("读取值:"+count);
                fis.close();
                // 清空response
                response.reset();
                // 设置response的Header
                response.addHeader("Content-Disposition", "attachment;filename=" + filename);//new String(filename.getBytes("utf-8"),"utf-8")
                response.addHeader("Content-Length", "" + file.length());
            } catch (IOException ex) {
            	log.error(ex.getMessage());
            }
        	
        	try(OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
                   ) {
        		 response.setContentType("application/octet-stream");
                 toClient.write(buffer);
                 toClient.flush();
                 toClient.close();
    		} catch (Exception e) {
    			log.error(e.getMessage());
    		}
        }
    }

    @Override
    public R<FilePreviewVO> filePreview(String apiVersion, String fileId) {
        UploadFile uploadFile = fileUploadService.selectFileById(fileId);
        FilePreviewVO previewVO = new FilePreviewVO();
        if (null != uploadFile){
            previewVO.setFileId(uploadFile.getId());
            previewVO.setFileName(uploadFile.getFileName());
            previewVO.setFilePath(uploadFile.getFileStoreAddress());
            previewVO.setPreviewUrl(uploadFile.getPreViewUrl());
        }
        return ok(previewVO);
    }

    @Override
    public R<FileDeleteVO> fileDelete(String apiVersion, String fileId) {
        //根据fileId查询文件
        UploadFile fileById = fileUploadService.selectFileById(fileId);
        FileDeleteVO deleteVO = new FileDeleteVO();
        String name = null;
        if (null != fileById){
            name = fileById.getOriginalFileName();
            int i = fileUploadService.deleteFile(fileId, IsDeleteEnum.YES.getKey());
            if (i == 1){
                deleteVO.setMessage(name+"删除成功");
                return ok(deleteVO);
            }
        }else {
            throw new MsgException(CodeEnum.FILE_IS_NOT_EXISTENT);
        }
        deleteVO.setMessage(name+"删除失败");
        return ok(deleteVO);
    }

}
